package com.example.common.websocket;

import com.example.common.config.GetHttpSessionConfig;
import com.example.common.config.WebSocketConfig;
import io.swagger.annotations.Scope;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocket服务
 * WebSocket组件  需要用配置类进行注册
 * WebSocket是基于TCP的一种新的网络协议。它实现了浏览器和服务器全工通信——浏览器和服务器只需要完成
 *一次握手,两者之间就可以创建持久性的连接,并进行双向的数据传输
 *
 * @author ding
 * @since 2024/7/22
 */
@Component
@ConditionalOnClass(value = WebSocketConfig.class)
@ServerEndpoint(value = "/socket/{userId}")
public class WebSocketServe {

    //存放会话对象
    private static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();

    private HttpSession httpSession;

    /**
     * 连接简历成功调用的方法
     * 变成类似客户端的回调方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId, EndpointConfig config) {
        //将 session 对象进行保持
        this.httpSession = (HttpSession)config.getUserProperties().get(HttpSession.class.getName());
        //获取请求session中的数据
//        String user = (String) this.httpSession.getAttribute("user");
        System.out.println("客户端:" + userId + "建立连接");
        sessionMap.put(userId,session);
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message   //客户端发送过来的消息,类似Controller包下的方法
     * @param userId
     */
    @OnMessage
    public void onMessage(String message,  @PathParam("userId") String userId) {
        System.out.println("收到来自客户端:" + userId + "的消息:" + message);
    }

    /**
     * 连接关闭调用的方法
     * @param userId
     */
    @OnClose
    public void onClose(@PathParam("userId")String userId){
        System.out.println("断开连接:" + userId);
        sessionMap.remove(userId);     //清理会话
    }

    /**
     * onMessage 是有一个消息中专站
     * @param message
     */
    public void sendToAllClient(String message){    //将session取出,向每一个客户端发送消息message
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 点对点发送
     * @param message   将要发送的消息
     * @param userId
     */
    public void sendToClient(String message, String userId) {
        Session session = sessionMap.get(userId);
        if (session != null) {
            try{
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}
